<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>我的webrtc网关</title>
		<script src="https://unpkg.com/vue@next"></script>
		<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
		
		<style>
			video {
				background-color: darkgray;
				width: 340px;
				height: 260px;
			}
		</style>
	</head>
	<body>
		<div id="app">
			<div>
				<button @click="start" :disabled="connectFlag">连接服务</button>
				<button @click="leave" :disabled="!connectFlag">断开连接</button>
			</div>
			<div>
				<div style="float:left; margin-right: 20px;">
					<h1>Local:</h1>
					<video autoplay="true" muted="true" playsinline id="localvideo"></video>
					<!--<h2>offer SDP:</h2>
					<textarea rows="10" v-model="offerSdp"></textarea>-->
				</div>
				<div style="float:left;">
					<h1>Remote:</h1>
					<video autoplay="true" playsinline id="remotevideo"></video>
					<!--<h2>answer SDP:</h2>
					<textarea rows="10" v-model="answerSdp"></textarea>-->
				</div>
				<div style="clear:both; width: 0;height: 0;"></div>
			</div>
		</div>
		
		<script>
			const app = Vue.createApp({
				data() {
					return {
						connectFlag: false, 
						wsClient: null,
						roomId: '0',
						userId: '0',
						userName: 'zhangsan',
						state: 'init',
						localVideo: null,
						localStream: null,
						remoteVideo: null,
						remoteStream: null,
						rtcPeer1: null
					}
				},
				methods: {
					start() {
						if(!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
							console.log('getUserMedia is not supported!')
							return
						}
						var constraints = {
							video: true,
							audio: true
						}
						navigator.mediaDevices.getUserMedia(constraints).then(stream => {
							console.log('getUserMedia success!')
							this.localVideo.srcObject = stream
							this.localStream = stream
							this.connectWsServer()
						}).catch(err => {
							console.error('failed to get media stream:' + err)
						})
					},
					connectWsServer() {
						var baseUrl = 'ws://172.16.208.2:6310'
						
						console.log('Connecting to WebSocket server at ' + baseUrl)
						this.wsClient = new WebSocket(baseUrl)
						
						this.wsClient.onclose = () => {
							console.error('web channel closed')
						};
						this.wsClient.onerror = (error) => {
							console.error('web channel error: ' + error)
						};
						this.wsClient.onopen = () => {
							console.log('WebSocket connect')
							this.joinRoom()
						}
						this.wsClient.onmessage = this.recvWebsocketMsg
					},
					recvWebsocketMsg(ev) {
						console.log('recv  msg ' + ev.data)
						let serverOrderObj =  JSON.parse(ev.data)
						if (serverOrderObj.orderType === 'joined') {
							this.handleJoinedOrder()
						} else if (serverOrderObj.orderType === 'createOffer') {
							this.handleRecCreateOffer(serverOrderObj)
						}
					},
					joinRoom()
					{
						let obj = {
							orderType: 'join',
							roomId: this.roomId,
							userId: this.userId,
							userName: this.userName
						}
						this.wsClient.send(JSON.stringify(obj))
					},
					handleJoinedOrder() {
						this.state = 'joined'
						console.log("join room success")
						this.createPeerConnection()
					},
					handleRecCreateOffer(serverOrderObj) {
						console.log('offer sdp is ', serverOrderObj.msg)
						this.rtcPeer1.setRemoteDescription(new RTCSessionDescription(serverOrderObj.msg))
						this.rtcPeer1.createAnswer().then(answerDesc => {
							console.log('answer sdp is ', answerDesc)
							this.rtcPeer1.setLocalDescription(answerDesc)
							this.sendMessage("answerOffer", answerDesc)
						}).catch(err => {
							console.log('createAnswer error', err)
						})
					},
					createPeerConnection() {
						if(this.rtcPeer1)
						{
							return
						}
						
						var config = {
							iceServers: [{
								// urls: 'turn:stun.al.learningrtc.cn:3478'
								urls: 'turn:172.16.208.2:3478',
								credential: 'a2886015',
								username: 'wenke'
							}]
						}
						this.rtcPeer1 = new RTCPeerConnection(config)
						
						this.rtcPeer1.onicecandidate = event => {
							if(event.candidate) {
								console.log('rtcPeer1 get ice candidate', event)
								this.sendMessage('candidate', event.candidate.candidate)
							}
						}
						
						this.rtcPeer1.ontrack = event => {
							console.log("get track", event)
							this.remoteVideo.srcObject = event.streams[0]
						}
						// 先将本地流的轨信息添加到RTCPeerConnection中
						this.localStream.getTracks().forEach(track => {
							this.rtcPeer1.addTrack(track, this.localStream)
						})
					},
					trigerMediaInfoNegotiate() { // 因为现在是webrtc网关主动发送createOffer触发媒体协商，所以这个函数用不上
						if(this.state !== 'joined' || !this.rtcPeer1) {
							return;
						}
						var offerOptions = {
							offerToReceiveAudio: 1,
							offerToReceiveVideo: 1
						}
						this.rtcPeer1.createOffer(offerOptions).then(desc => {
							// this.offerSdp = desc.sdp
							// desc是RTCSessionDescription 对象，setLocalDescription用于获取其所有的candidate
							console.log('offer sdp data', desc)
							this.rtcPeer1.setLocalDescription(desc)
							this.sendMessage('createOffer', desc)
						}).catch(err => {
							console.error('RTCPeerConnection 2 create answer failed' + err)
						})
					},
					sendMessage(order, msg) {
						let obj = {
							orderType: order,
							roomId: this.roomId,
							userId: this.userId,
							userName: this.userName,
							msg: msg
						}
						this.wsClient.send(JSON.stringify(obj))
					},
					leave() {
						
					}
				},
				mounted () {
					this.localVideo = document.querySelector('#localvideo')
					this.remoteVideo = document.querySelector('#remotevideo')
				}
			})
			
			var vm = app.mount('#app')
			console.log(vm)
		</script>
	</body>
</html>
